package com.common.handmark.pulltorefresh.library;

import android.content.Context;
import android.os.Build;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.FrameLayout;

import com.common.dongqiuhui.apps.comm.tools.BallLog;

public class PullToRefreshZoomListView extends PullToRefreshListView {
	
	private static final String TAG = PullToRefreshZoomListView.class.getSimpleName();
	
	protected View mHeaderView;//头部View
	protected View mZoomView;//缩放拉伸View
	private FrameLayout mHeaderContainer;
    private int mHeaderHeight;
    private ScalingRunnable mScalingRunnable;
    private boolean isZoomEnabled = true;
    private boolean isParallax = false;
    private boolean isZooming = false;
    private boolean isHideHeader = false;
    
    private static final Interpolator sInterpolator = new Interpolator() {
        public float getInterpolation(float paramAnonymousFloat) {
            float f = paramAnonymousFloat - 1.0F;
            return 1.0F + f * (f * (f * (f * f)));
        }
    };
    
	public PullToRefreshZoomListView(Context context) {
		super(context);
		init();
	}
	public PullToRefreshZoomListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	public PullToRefreshZoomListView(Context context, PullToRefreshBase.Mode mode) {
		super(context, mode);
		init();
	}
	public PullToRefreshZoomListView(Context context, PullToRefreshBase.Mode mode,
			PullToRefreshBase.AnimationStyle style) {
		super(context, mode, style);
		init();
	}

	private void init() {
		mHeaderContainer = new FrameLayout(getContext());
		mScalingRunnable = new ScalingRunnable();
		setShowViewWhileRefreshing(false);
		getRefreshableView().addHeaderView(mHeaderContainer);
	}
	
    public View getZoomView() {
        return mZoomView;
    }

    public View getHeaderView() {
        return mHeaderView;
    }
    
    public boolean isPullToZoomEnabled() {
        return isZoomEnabled;
    }

    public boolean isZooming() {
        return isZooming;
    }

    public boolean isParallax() {
        return isParallax;
    }

    public boolean isHideHeader() {
        return isHideHeader;
    }

    public void setZoomEnabled(boolean isZoomEnabled) {
        this.isZoomEnabled = isZoomEnabled;
    }

    public void setParallax(boolean isParallax) {
        this.isParallax = isParallax;
    }

    public void setHideHeader(boolean isHideHeader) {//header显示才能Zoom
        if (isHideHeader != isHideHeader()) {
        	this.isHideHeader = isHideHeader;
            if (isHideHeader) {
                removeHeaderView();
            } else {
                updateHeaderView();
            }
        }
    }
    
    public void setHeaderView(View headerView) {
        if (headerView != null) {
            this.mHeaderView = headerView;
            updateHeaderView();
        }
    }
    
    public void setZoomView(View zoomView) {
        if (zoomView != null) {
            this.mZoomView = zoomView;
            updateHeaderView();
        }
    }
    
    private boolean canRemoveHeaderView() {
    	return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
    }
    
    /**
     * 移除HeaderView
     * 如果要兼容API 9,需要修改此处逻辑，API 11以下不支持动态添加header
     */
    private void removeHeaderView() {
        if (mHeaderContainer != null) {
        	try {
        		if (canRemoveHeaderView()) {
	        		getRefreshableView().removeHeaderView(mHeaderContainer);
        		}
        	} catch (Throwable e) {
        		BallLog.e(TAG, "removeHeaderView e[" + e + "]");
        	}
        }
    }
    
    /**
     * 更新HeaderView  先移除-->再添加zoomView、HeaderView -->然后添加到listView的head
     * 如果要兼容API 9,需要修改此处逻辑，API 11以下不支持动态添加header
     */
    private void updateHeaderView() {
    	BallLog.e(TAG, "updateHeaderView mHeaderContainer[" + mHeaderContainer + "]");
        if (mHeaderContainer != null) {
        	removeHeaderView();
            mHeaderContainer.removeAllViews();

            if (mZoomView != null) {
                mHeaderContainer.addView(mZoomView);
            }

            if (mHeaderView != null) {
                mHeaderContainer.addView(mHeaderView);
            }

            mHeaderHeight = mHeaderContainer.getHeight();
            if (canRemoveHeaderView()) {
            	getRefreshableView().addHeaderView(mHeaderContainer);
            }
        }
    }
    
    @Override
    protected void onRefreshing(boolean doScroll) {
    	// super.onRefreshing(doScroll);
    	BallLog.i(TAG, "onRefreshing");
        mScalingRunnable.startAnimation(200L);
        callRefreshListener();
    }
    
    @Override
    protected void onReset() {
    	super.onReset();
    	BallLog.i(TAG, "onReset");
    	// mScalingRunnable.startAnimation(200L);
    }
    
    @Override
    protected void onPullToRefresh() {
    	//super.onPullToRefresh();
    }
    
    @Override
    protected void smoothScrollTo(int newScrollValue, long duration, long delayMillis,
    		PullToRefreshBase.OnSmoothScrollFinishedListener listener) {
    	mScalingRunnable.startAnimation(200L);
    }
    
	@Override
	protected void setHeaderScroll(int newScrollValue) {
		BallLog.i(TAG, "setHeaderScroll newScrollValue[" + newScrollValue + "] mHeaderHeight[" + mHeaderHeight + "]");
        if (mScalingRunnable != null && !mScalingRunnable.isFinished()) {
            mScalingRunnable.abortAnimation();
        }

        ViewGroup.LayoutParams localLayoutParams = mHeaderContainer.getLayoutParams();
        localLayoutParams.height = Math.abs(newScrollValue) + mHeaderHeight;
        mHeaderContainer.setLayoutParams(localLayoutParams);
	}
	
	/**
     * 设置HeaderView高度
     *
     * @param width  宽
     * @param height 高
     */
    public void setHeaderViewSize(int width, int height) {
    	BallLog.i(TAG, "setHeaderViewSize mHeaderContainer[" + mHeaderContainer + "] width[" + width + "] height[" + height + "]");
        if (mHeaderContainer != null) {
            Object localObject = mHeaderContainer.getLayoutParams();
            if (localObject == null) {
                localObject = new AbsListView.LayoutParams(width, height);
            }
            ((ViewGroup.LayoutParams) localObject).width = width;
            ((ViewGroup.LayoutParams) localObject).height = height;
            mHeaderContainer.setLayoutParams((ViewGroup.LayoutParams) localObject);
            mHeaderHeight = height;
        }
    }
    
    public void setHeaderLayoutParams(AbsListView.LayoutParams layoutParams) {
        if (mHeaderContainer != null) {
            mHeaderContainer.setLayoutParams(layoutParams);
            mHeaderHeight = layoutParams.height;
        }
    }

    protected void onLayout(boolean paramBoolean, int l, int t, int r, int b) {
        super.onLayout(paramBoolean, l, t, r, b);
        BallLog.i(TAG, "onLayout l[" + l + "] t[" + t + "] r[" + r + "] b[" + b + "] mHeaderHeight[" + mHeaderHeight + "]");
        if (mHeaderHeight == 0 && mHeaderContainer != null) {
            mHeaderHeight = mHeaderContainer.getHeight();
        }
        BallLog.i(TAG, "onLayout mHeaderHeight[" + mHeaderHeight + "]");
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    	super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
    	if (mZoomView != null && !isHideHeader() && isPullToZoomEnabled()) {
            float f = mHeaderHeight - mHeaderContainer.getBottom();
            BallLog.i(TAG, "onScroll f[" + f + "]");
            if (isParallax()) {
                if ((f > 0.0F) && (f < mHeaderHeight)) {
                    int i = (int) (0.65D * f);
                    mHeaderContainer.scrollTo(0, -i);
                } else if (mHeaderContainer.getScrollY() != 0) {
                    mHeaderContainer.scrollTo(0, 0);
                }
            }
        }
    }
    
	class ScalingRunnable implements Runnable {
        protected long mDuration;
        protected boolean mIsFinished = true;
        protected float mScale;
        protected long mStartTime;

        ScalingRunnable() {
        }

        public void abortAnimation() {
            mIsFinished = true;
        }

        public boolean isFinished() {
            return mIsFinished;
        }

        public void run() {
            if (mZoomView != null) {
                float f2;
                ViewGroup.LayoutParams localLayoutParams;
                BallLog.i(TAG, "ScalingRunnable mScale[" + mScale + "]");
                if ((!mIsFinished) && (mScale > 1.0D)) {
                    float f1 = ((float) SystemClock.currentThreadTimeMillis() - (float) mStartTime) / (float) mDuration;
                    BallLog.i(TAG, "ScalingRunnable f1[" + f1 + "]");
                    f2 = mScale - (mScale - 1.0F) * PullToRefreshZoomListView.sInterpolator.getInterpolation(f1);
                    localLayoutParams = mHeaderContainer.getLayoutParams();
                    BallLog.i(TAG, "ScalingRunnable --> f2 = " + f2);
                    if (f2 > 1.0F) {
                        localLayoutParams.height = ((int) (f2 * mHeaderHeight));
                        mHeaderContainer.setLayoutParams(localLayoutParams);
                        post(this);
                        return;
                    } else {
                    	localLayoutParams.height = ((int) (mHeaderHeight));
                        mHeaderContainer.setLayoutParams(localLayoutParams);
                    }
                    mIsFinished = true;
                }
            }
        }

        public void startAnimation(long paramLong) {
            if ((mIsFinished) && (mZoomView != null)) {
                mStartTime = SystemClock.currentThreadTimeMillis();
                mDuration = paramLong;
                mScale = ((float) (mHeaderContainer.getBottom()) / mHeaderHeight);
                mIsFinished = false;
                BallLog.i(TAG, "startAnimation mScale[" + mScale + "]");
                post(this);
            }
        }
    }
}
